from tortoise.expressions import Q
from tortoise.functions import Sum
from app.controllers.appointment.project import appointment_project_controller
from app.controllers.goods.sku import sku_controller
from app.core.crud import CRUDBase
from app.models import GoodsSku, OrdersGoods, CustomerLevel
from app.models.goods import Goods,GoodsCategory
from app.schemas.goods import GoodsCreate, GoodsUpdate, GoodsSkuCreate, GoodsSkuUpdate
from tortoise.transactions import in_transaction
from fastapi.responses import JSONResponse
from app.log.log import logger

class GoodsController(CRUDBase[Goods, GoodsCreate, GoodsUpdate]):
    def __init__(self):
        super().__init__(model=Goods)

    async def do_list(self, page: int, page_size: int, search: Q = Q()):
        try:
            # 获取符合搜索条件的商品查询
            query = self.model.filter(search)
            # 获取商品总数
            total = await query.count()
            # 获取分页后的商品数据
            objs = await query.offset((page - 1) * page_size).limit(page_size).order_by('-id')
            # 将商品对象转为字典
            data = [await obj.to_dict() for obj in objs]
            # 获取所有商品的ID
            goods_ids = [goods['id'] for goods in data]
            # 批量查询与这些商品ID相关的所有SKU
            sku_q = Q(goods_id__in=goods_ids)
            sku_total, sku_data = await sku_controller.do_list(page=1, page_size=1000, search=sku_q)
            # 创建一个商品ID到SKU数据的映射
            sku_map = {}
            for sku in sku_data:
                sku_map.setdefault(sku['goods_id'], []).append(sku)
            # 为每个商品填充相关的SKU数据
            for goods in data:
                goods['sku'] = sku_map.get(goods['id'], [])
            return total, data
        except Exception as e:
            # 如果发生异常，记录错误并返回空数据
            print(f"获取商品列表失败: {str(e)}")
            return 0, []  # 返回空的商品列表和0条总数

    async def do_detail(self,data_id:int):
        obj = await self.get(id=data_id)
        data = await obj.to_dict()
        ##查一下购买商品详细信息
        goods_q = Q(goods_id=data['id'])
        goods_total, goods_data = await sku_controller.do_list(page=1, page_size=100, search=goods_q)
        data['sku'] = goods_data
        return data

    @staticmethod
    async def do_create_sku(goods_id:int,obj_in):
        q = Q(goods_id=goods_id)
        await sku_controller.do_delete(search=q)
        if obj_in.sku:
            for sku_item in obj_in.sku:
                sku_data = {
                    "goods_id": goods_id,
                    "sku_name": sku_item.get('sku_name'),
                    "sku_kc": sku_item.get('sku_kc'),
                    "sku_cover": sku_item.get('sku_cover'),
                    "sku_level": sku_item.get('sku_level'),
                    "can_do": sku_item.get('can_do'),
                    "include": sku_item.get('include'),
                }

                sku_in = GoodsSkuCreate(**sku_data)
                await sku_controller.do_create(sku_in)
        return True

    async def do_create(self, obj_in: GoodsCreate):
        logger.info(f"新增商品")
        try:
            async with in_transaction() as transaction:
                attrs = obj_in.info_goods
                for item in attrs:
                    attr_value = len(item.get("attr_value", []))
                    attr_price = len(item.get("attr_price", []))
                    num = attr_value - attr_price
                    if num > 0:
                        for i in range(num):
                            item["attr_price"].append("0")
                ret = await self.create(obj_in=obj_in)
                await self.do_create_sku(goods_id=ret.id, obj_in=obj_in)
                logger.info(f"新增商品{ret.id}")
                return JSONResponse(content={"code": 200, "message": f"修改成功"}, status_code=200)
        except Exception as e:
            return JSONResponse(content={"code": 400, "message": f"创建过程中发生错误{e}"}, status_code=400)

    async def do_update(self, obj_in: GoodsUpdate):
        logger.info(f"编辑商品{obj_in.id}")
        try:
            # async with in_transaction() as transaction:
            new_sku = obj_in.sku
            sku_ids = []
            goods_id = obj_in.id
            ##sku
            for item in new_sku:
                item_id = item.get("id",0)
                if item_id == 0:
                    item['goods_id'] = goods_id
                    item_obj = GoodsSkuCreate(**item)
                    ret = await sku_controller.do_create(item_obj)
                    sku_ids.append(ret.id)
                else:
                    sku_ids.append(item_id)
                    item_obj = GoodsSkuUpdate(**item)
                    await sku_controller.do_update(item_obj)
                await GoodsSku.filter(goods_id=goods_id).exclude(id__in=sku_ids).delete()
                ##attr
                attrs = obj_in.info_goods
                for item in attrs:
                    attr_value = len(item.get("attr_value", []))
                    attr_price = len(item.get("attr_price",[]))
                    num = attr_value - attr_price
                    if num>0 :
                        for i in range(num):
                            item["attr_price"].append("0")
                await self.update(id=obj_in.id, obj_in=obj_in)
                return JSONResponse(content={"code": 200, "message": f"修改成功"}, status_code=200)
        except Exception as e:
            return JSONResponse(content={"code": 400, "message": f"编辑过程中发生错误{e}"}, status_code=400)

    async def do_delete(self, data_id: int):
        await self.remove(id=data_id)
        await appointment_project_controller.do_update_good(data_id)
        return True

    @staticmethod
    async def categorys():
        objs = await GoodsCategory.all().values("id", "name")
        data = dict()
        for obj in objs:
            data[obj['id']] = obj['name']
        return data

    @staticmethod
    async def sale_num(goods_id:int):
        result = await OrdersGoods.filter(goods_id=goods_id).annotate(total_num=Sum('num')).first()
        total_num = float(result.total_num) if result.total_num else 0
        return total_num

    ##根据sku查询总库存和价格区间
    @staticmethod
    async def sku_format(sku):
        kc = 0
        # 初始化最大值和最小值
        min_value = float('inf')  # 初始化为无穷大
        max_value = float('-inf')  # 初始化为无穷小
        # 遍历 SKU 列表
        for item in sku:
            kc += item['sku_kc']
            sku_levels = item['sku_level']
            for value in sku_levels:
                if value is not None:  # 忽略 None 值
                    if value < min_value:
                        min_value = value
                    if value > max_value:
                        max_value = value
        return kc,min_value,max_value

goods_controller = GoodsController()
